{
 "cells": [
  {
   "cell_type": "raw",
   "id": "7b68af90-bfab-4407-93b6-d084cf948b4b",
   "metadata": {},
   "source": [
    "---\n",
    "sidebar_position: 1\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1925a807-fa01-44bc-8a03-d9907311c7f9",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true
   },
   "source": [
    "## Agents\n",
    "\n",
    "Chains are great when we know the specific sequence of tool usage needed for any user input. But for certain use cases, how many times we use tools depends on the input. In these cases, we want to let the model itself decide how many times to use tools and in what order. [Agents](/docs/modules/agents/) let us do just this.\n",
    "\n",
    "LangChain comes with a number of built-in agents that are optimized for different use cases. Read about all the [agent types here](/docs/modules/agents/agent_types/).\n",
    "\n",
    "As an example, let's try out the OpenAI tools agent, which makes use of the new OpenAI tool-calling API (this is only available in the latest OpenAI models, and differs from function-calling in that the model can return multiple function invocations at once).\n",
    "\n",
    "![agent](../../../static/img/tool_agent.svg)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c224a321-2f5a-410c-b466-a10d0199bad8",
   "metadata": {},
   "source": [
    "## Setup\n",
    "\n",
    "We'll need to install the following packages:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f6303995-a8f7-4504-8b29-e227683f375e",
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install --upgrade --quiet langchain langchain-openai"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a33915ce-00c5-4379-8a83-c0053e471cdb",
   "metadata": {},
   "source": [
    "And set these environment variables:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "54667a49-c226-486d-a887-33120c90cc91",
   "metadata": {},
   "outputs": [],
   "source": [
    "import getpass\n",
    "import os\n",
    "\n",
    "os.environ[\"OPENAI_API_KEY\"] = getpass.getpass()\n",
    "\n",
    "# If you'd like to use LangSmith, uncomment the below\n",
    "# os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
    "# os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aaaad3ad-085b-494e-84aa-9cb3e983c80b",
   "metadata": {},
   "source": [
    "## Create tools\n",
    "\n",
    "First, we need to create some tool to call. For this example, we will create custom tools from functions. For more information on creating custom tools, please see [this guide](/docs/modules/agents/tools/)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "1c44ba79-6ab2-4d55-8247-82fca4d9b70c",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.tools import tool\n",
    "\n",
    "\n",
    "@tool\n",
    "def multiply(first_int: int, second_int: int) -> int:\n",
    "    \"\"\"Multiply two integers together.\"\"\"\n",
    "    return first_int * second_int\n",
    "\n",
    "\n",
    "@tool\n",
    "def add(first_int: int, second_int: int) -> int:\n",
    "    \"Add two integers.\"\n",
    "    return first_int + second_int\n",
    "\n",
    "\n",
    "@tool\n",
    "def exponentiate(base: int, exponent: int) -> int:\n",
    "    \"Exponentiate the base to the exponent power.\"\n",
    "    return base**exponent\n",
    "\n",
    "\n",
    "tools = [multiply, add, exponentiate]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a3d0c8ca-72bd-4187-b1e6-f5eef92eeb52",
   "metadata": {},
   "source": [
    "## Create prompt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "e27a4e1a-938b-4b60-8e32-25e4ee530274",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain import hub\n",
    "from langchain.agents import AgentExecutor, create_openai_tools_agent\n",
    "from langchain_openai import ChatOpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "bcc9536e-0328-4e29-9d3d-133f3e63e589",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================\u001b[1m System Message \u001b[0m================================\n",
      "\n",
      "You are a helpful assistant\n",
      "\n",
      "=============================\u001b[1m Messages Placeholder \u001b[0m=============================\n",
      "\n",
      "\u001b[33;1m\u001b[1;3m{chat_history}\u001b[0m\n",
      "\n",
      "================================\u001b[1m Human Message \u001b[0m=================================\n",
      "\n",
      "\u001b[33;1m\u001b[1;3m{input}\u001b[0m\n",
      "\n",
      "=============================\u001b[1m Messages Placeholder \u001b[0m=============================\n",
      "\n",
      "\u001b[33;1m\u001b[1;3m{agent_scratchpad}\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "# Get the prompt to use - you can modify this!\n",
    "prompt = hub.pull(\"hwchase17/openai-tools-agent\")\n",
    "prompt.pretty_print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85e9875a-d8d4-4712-b3f0-b513c684451b",
   "metadata": {},
   "source": [
    "## Create agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a1c5319d-6609-449d-8dd0-127e9a600656",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Choose the LLM that will drive the agent\n",
    "# Only certain models support this\n",
    "model = ChatOpenAI(model=\"gpt-3.5-turbo-1106\", temperature=0)\n",
    "\n",
    "# Construct the OpenAI Tools agent\n",
    "agent = create_openai_tools_agent(model, tools, prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "c86bfe50-c5b3-49ed-86c8-1fe8dcd0c83a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create an agent executor by passing in the agent and tools\n",
    "agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "448d5ef2-9820-44d0-96d3-ff1d648e4b01",
   "metadata": {},
   "source": [
    "## Invoke agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "c098f8df-fd7f-4c13-963a-8e34194d3f84",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
      "\u001b[32;1m\u001b[1;3m\n",
      "Invoking: `exponentiate` with `{'base': 3, 'exponent': 5}`\n",
      "\n",
      "\n",
      "\u001b[0m\u001b[38;5;200m\u001b[1;3m243\u001b[0m\u001b[32;1m\u001b[1;3m\n",
      "Invoking: `add` with `{'first_int': 12, 'second_int': 3}`\n",
      "\n",
      "\n",
      "\u001b[0m\u001b[33;1m\u001b[1;3m15\u001b[0m\u001b[32;1m\u001b[1;3m\n",
      "Invoking: `multiply` with `{'first_int': 243, 'second_int': 15}`\n",
      "\n",
      "\n",
      "\u001b[0m\u001b[36;1m\u001b[1;3m3645\u001b[0m\u001b[32;1m\u001b[1;3m\n",
      "Invoking: `exponentiate` with `{'base': 3645, 'exponent': 2}`\n",
      "\n",
      "\n",
      "\u001b[0m\u001b[38;5;200m\u001b[1;3m13286025\u001b[0m\u001b[32;1m\u001b[1;3mThe result of raising 3 to the fifth power and multiplying that by the sum of twelve and three, then squaring the whole result is 13,286,025.\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'input': 'Take 3 to the fifth power and multiply that by the sum of twelve and three, then square the whole result',\n",
       " 'output': 'The result of raising 3 to the fifth power and multiplying that by the sum of twelve and three, then squaring the whole result is 13,286,025.'}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent_executor.invoke(\n",
    "    {\n",
    "        \"input\": \"Take 3 to the fifth power and multiply that by the sum of twelve and three, then square the whole result\"\n",
    "    }\n",
    ")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "poetry-venv",
   "language": "python",
   "name": "poetry-venv"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
